package com.example.travel.service;

import com.example.travel.bean.*;
import com.example.travel.mapper.HotelMapper;
import com.example.travel.mapper.OrderMapper;
import com.example.travel.mapper.*;
import com.example.travel.mapper.SiteMapper;
import com.example.travel.utils.DateFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.example.travel.utils.PubDef;
import com.example.travel.utils.RedisLock;
import org.springframework.web.bind.annotation.RequestParam;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private SiteMapper siteMapper;;

    @Autowired
    private HotelMapper hotelMapper;;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private ActivityMapper activityMapper;

    @Autowired
    private LineMapper lineMapper;

    @Autowired
    private RedisLock redisLock;

    /**
     * 景区门票下单
     */
    public int buySite(String userName, int siteID, int num, String startDate) {
        try {
            SiteBean buySite = siteMapper.getSiteById(siteID);
            OrderBean order = new OrderBean();
            order.setSourceId(siteID);
            order.setOrderType("景区预订");
            BigDecimal price = new BigDecimal(buySite.getSitePrice());
            order.setOrderPrice(price.multiply(new BigDecimal(num)));
            order.setOrderUser(userName);
            order.setOrderNum(num);

            DateFormatter dateFormatter = new DateFormatter();
            order.setOrderDate(dateFormatter.getDate());
            order.setOrderRefund(0);//默认未退款
            order.setOrderStartDate(PubDef.formatTime(startDate));
            order.setOrderCode(PubDef.generateOrderCode());
            return orderMapper.buySite(order);
        } catch (Exception e) {
            System.out.println("出错啦:" + e.getMessage());
            return -1;
        }

    }

    /**
     * 民俗下单（带Redis锁和余量检查）
     */
    public int buyHotel(String userName, int hotelID, int num, String startDate, String endDate) {
        // 生成锁的唯一标识
        String lockKey = "hotel:lock:" + hotelID;
        String lockValue = UUID.randomUUID().toString();
        long lockExpireTime = 10; // 锁过期时间10秒
        
        try {
            // 尝试获取Redis分布式锁
            if (!redisLock.tryLock(lockKey, lockValue, lockExpireTime)) {
                System.out.println("获取民宿锁失败，可能存在并发操作");
                return -2; // 返回-2表示获取锁失败
            }
            
            try {
                // 获取民宿信息
                HotelBean buyHotel = hotelMapper.getHotelById(hotelID);
                if (buyHotel == null) {
                    System.out.println("民宿不存在: " + hotelID);
                    return -3; // 返回-3表示民宿不存在
                }
                
                // 检查余量是否充足
                int currentRemain = Integer.parseInt(buyHotel.getHotelRemain());
                if (currentRemain < num) {
                    System.out.println("民宿余量不足: 当前余量=" + currentRemain + ", 需要数量=" + num);
                    return -4; // 返回-4表示余量不足
                }
                
                // 扣除余量
                int deductResult = hotelMapper.deductHotelRemain(hotelID, num);
                if (deductResult <= 0) {
                    System.out.println("扣除民宿余量失败，可能余量不足");
                    return -5; // 返回-5表示扣除余量失败
                }
                
                // 创建订单
                OrderBean order = new OrderBean();
                order.setSourceId(hotelID);
                order.setOrderType("民宿预订");
                BigDecimal price = new BigDecimal(buyHotel.getHotelPrice());
                order.setOrderPrice(price.multiply(new BigDecimal(num)));
                order.setOrderUser(userName);
                order.setOrderNum(num);

                DateFormatter dateFormatter = new DateFormatter();
                order.setOrderDate(dateFormatter.getDate());
                order.setOrderRefund(0);
                order.setOrderStartDate(PubDef.formatTime(startDate));
                order.setOrderEndDate(PubDef.formatTime(endDate));
                order.setOrderCode(PubDef.generateOrderCode());
                
                int result = orderMapper.buyHotel(order);
                if (result <= 0) {
                    // 如果订单创建失败，需要回滚余量
                    hotelMapper.addHotelRemain(hotelID, num);
                    System.out.println("订单创建失败，已回滚余量");
                }
                return result;
            } finally {
                // 释放Redis锁
                redisLock.releaseLock(lockKey, lockValue);
            }
        } catch (NumberFormatException e) {
            System.out.println("余量格式错误: " + e.getMessage());
            return -6; // 返回-6表示数据格式错误
        } catch (Exception e) {
            System.out.println("民宿下单出错: " + e.getMessage());
            e.printStackTrace();
            return -1; // 返回-1表示其他异常
        }
    }

    /**
     * 美食下单（带Redis锁和余量检查）
     */
    public int buyProduct(String userName, int productID, int num, String startDate) {
        // 生成锁的唯一标识
        String lockKey = "product:lock:" + productID;
        String lockValue = UUID.randomUUID().toString();
        long lockExpireTime = 10; // 锁过期时间10秒
        
        try {
            // 尝试获取Redis分布式锁
            if (!redisLock.tryLock(lockKey, lockValue, lockExpireTime)) {
                System.out.println("获取美食锁失败，可能存在并发操作");
                return -2; // 返回-2表示获取锁失败
            }
            
            try {
                // 获取美食信息
                ProductBean buyProduct = productMapper.getProductById(productID);
                if (buyProduct == null) {
                    System.out.println("美食不存在: " + productID);
                    return -3; // 返回-3表示美食不存在
                }
                
                // 检查余量是否充足
                int currentRemain = Integer.parseInt(buyProduct.getProductRemain());
                if (currentRemain < num) {
                    System.out.println("美食余量不足: 当前余量=" + currentRemain + ", 需要数量=" + num);
                    return -4; // 返回-4表示余量不足
                }
                
                // 扣除余量（使用乐观锁，确保原子性）
                int deductResult = productMapper.deductProductRemain(productID, num);
                if (deductResult <= 0) {
                    System.out.println("扣除美食余量失败，可能余量不足");
                    return -5; // 返回-5表示扣除余量失败
                }
                
                // 创建订单
                OrderBean order = new OrderBean();
                order.setSourceId(productID);
                order.setOrderType("美食预定");
                BigDecimal price = new BigDecimal(buyProduct.getProductPrice());
                order.setOrderPrice(price.multiply(new BigDecimal(num)));
                order.setOrderUser(userName);
                order.setOrderNum(num);

                DateFormatter dateFormatter = new DateFormatter();
                order.setOrderDate(dateFormatter.getDate());
                order.setOrderRefund(0);
                order.setOrderStartDate(PubDef.formatTime(startDate));

                order.setOrderCode(PubDef.generateOrderCode());
                
                int result = orderMapper.buyProduct(order);
                if (result <= 0) {
                    // 如果订单创建失败，需要回滚余量
                    productMapper.addProductRemain(productID, num);
                    System.out.println("订单创建失败，已回滚余量");
                }
                return result;
            } finally {
                // 释放Redis锁
                redisLock.releaseLock(lockKey, lockValue);
            }
        } catch (NumberFormatException e) {
            System.out.println("余量格式错误: " + e.getMessage());
            return -6; // 返回-6表示数据格式错误
        } catch (Exception e) {
            System.out.println("美食下单出错: " + e.getMessage());
            e.printStackTrace();
            return -1; // 返回-1表示其他异常
        }
    }

    /**
     * 人文活动下单
     */
    public int buyActivity(String userName, int activityID, int num, String startDate) {
        try {
            // 获取活动信息
            ActivityBean buyActivity = activityMapper.getActivityById(activityID);
            OrderBean order = new OrderBean();
            order.setSourceId(activityID);
            order.setOrderType("人文活动");
            BigDecimal price = new BigDecimal(buyActivity.getActivityPrice());
            order.setOrderPrice(price.multiply(new BigDecimal(num)));
            order.setOrderUser(userName);
            order.setOrderNum(num);

            DateFormatter dateFormatter = new DateFormatter();
            order.setOrderDate(dateFormatter.getDate());
            order.setOrderRefund(0);
            order.setOrderStartDate(PubDef.formatTime(startDate));
            order.setOrderCode(PubDef.generateOrderCode());
            return orderMapper.buyActivity(order);
        } catch (Exception e) {
            System.out.println("出错啦:" + e.getMessage());
            return -1;
        }
    }

    /**
     * 旅游线路下单
     */
    public int buyLine(String userName, int lineID, int num, String startDate) {
        try {
            // 获取线路信息
            LineBean buyLine = lineMapper.getLineById(lineID);
            OrderBean order = new OrderBean();
            order.setSourceId(lineID);
            order.setOrderType("旅游线路");
            BigDecimal price = new BigDecimal(buyLine.getLinePrice());
            order.setOrderPrice(price.multiply(new BigDecimal(num)));
            order.setOrderUser(userName);
            order.setOrderNum(num);

            DateFormatter dateFormatter = new DateFormatter();
            order.setOrderDate(dateFormatter.getDate());
            order.setOrderRefund(0);
            order.setOrderStartDate(PubDef.formatTime(startDate));
            order.setOrderCode(PubDef.generateOrderCode());
            return orderMapper.buyLine(order);
        } catch (Exception e) {
            System.out.println("出错啦:" + e.getMessage());
            return -1;
        }
    }

    /**
     * 根据用户名查询订单列表
     */
    public List<OrderBean> getOrderList(String userName,int offset,int pageSize) {
        return orderMapper.getOrderList(userName,offset,pageSize);
    }

    /**
     * 获取最近的订单信息（用于管理员后台）
     */
    public List<OrderBean> getRecentOrders(int limit) {
        return orderMapper.getRecentOrders(limit);
    }

    /**
     * 退订
     */
    @Transactional(rollbackFor = Exception.class)
    public String refundOrder(int orderID,String userName,String orderCode) {
        String result;
        try{
            OrderBean refundOrder = orderMapper.getOrderById(orderID,userName,orderCode);
            if(refundOrder == null){
                result = "未查询到要退订的订单ID："+orderID+"-用户名："+userName+"-订单凭证："+orderCode;
                return result;
            } else if (refundOrder.getOrderRefund() != 0) {
                result = "该订单已经退订，请勿重复退订！";
                return result;
            }
            
            // 标记订单为退订状态
            int refundResult = orderMapper.refundOrder(orderID);
            if(refundResult != 1){
                result = "该订单可能已退订，请刷新界面";
                return result;
            }
            
            // 根据订单类型恢复资源余量
            String orderType = refundOrder.getOrderType();
            int orderNum = refundOrder.getOrderNum();
            int sourceId = refundOrder.getSourceId();
            
            if("美食预定".equals(orderType)){
                // 恢复美食余量
                int addResult = productMapper.addProductRemain(sourceId, orderNum);
                if(addResult <= 0){
                    throw new Exception("恢复美食余量失败，美食ID：" + sourceId);
                }
                result = "退订成功，美食余量已恢复";
            } else if("民宿预订".equals(orderType)){
                // 恢复民宿余量
                int addResult = hotelMapper.addHotelRemain(sourceId, orderNum);
                if(addResult <= 0){
                    throw new Exception("恢复民宿余量失败，民宿ID：" + sourceId);
                }
                result = "退订成功，民宿余量已恢复";
            } else {
                // 其他订单类型（景区预订、人文活动、旅游线路）不需要恢复余量
                result = "退订成功";
            }

        }catch (Exception e){
            System.out.println("退订异常：" + e.getMessage());
            result = "退订异常，请联系管理员，错误信息："+e.getMessage();
        }
        return result;
    }
}
